package com.mes.cloud.mail;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class MailAutoConfiguration {

    @Bean
    public MailSenderFactory mailSenderFactory(MailProperties mailProperties) {
        return new MailSenderFactory(mailProperties);
    }

    @Bean
    public MailService mailService(MailSenderFactory sender) {
        return new MailService(sender);
    }


    protected static class MailSenderFactory {
        public static final String DEFAULT_ENCODING = "UTF-8";

        private static final String DEFAULT_SENDER_NAME = "default";

        private Map<String, MailSender> senders = new HashMap<>();

        public MailSenderFactory(MailProperties mailProperties) {
            if (mailProperties != null && !mailProperties.getSenders().isEmpty()) {
                mailProperties.getSenders().forEach((name, config) -> senders.put(name, createSender(config)));
            }
        }

        private MailSender createSender(MailProperties.Config config) {
            MailSender sender = new MailSender();

            Properties mailProperties = new Properties();
            mailProperties.put("mail.transport.protocol", JavaMailSenderImpl.DEFAULT_PROTOCOL);
            mailProperties.put("mail.smtp.host", config.getHost());
            mailProperties.put("mail.smtp.auth", "true");
            mailProperties.put("mail.smtp.auth.mechanisms", "NTLM");
            mailProperties.put("mail.smtp.auth.ntlm.domain", config.getDomain());
            mailProperties.put("mail.smtp.port", config.getPort());
            //mailProperties.put("mail.debug", "true");
            sender.setJavaMailProperties(mailProperties);

            sender.setHost(config.getHost());
            sender.setPort(config.getPort());
            sender.setProtocol(JavaMailSenderImpl.DEFAULT_PROTOCOL);
            sender.setUsername(config.getUserName());
            sender.setPassword(config.getPassword());
            sender.setDefaultEncoding(DEFAULT_ENCODING);

            sender.setFrom(config.getFrom());

            return sender;
        }

        public MailSender getSender(String name) {
            if (senders.isEmpty()) {
                throw new RuntimeException("Unable to find mail sender service.");
            }

            MailSender sender = senders.get(name);
            if (sender != null) return sender;

            sender = senders.get(DEFAULT_SENDER_NAME);
            if (sender != null) return sender;

            return senders.values().stream().findFirst().get();
        }
    }

    protected static class MailSender extends JavaMailSenderImpl {
        private String from;

        public String getFrom() {
            return from;
        }

        public void setFrom(String from) {
            this.from = from;
        }
    }
}